home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / sndhrdw / seta.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  5KB  |  219 lines

  1. /***************************************************************************
  2.  
  3.                                 -= Seta Games =-
  4.  
  5.                     driver by    Luca Elia (eliavit@unina.it)
  6.  
  7.  
  8. Sound Chip:
  9.  
  10.     X1-010                     [Seta Custom?]
  11.     Unsigned 16 Bit PCM     [Fixed Per Game Pitch?]
  12.     16 Voices                [There's More Data Written!]
  13.  
  14. Format:
  15.  
  16.     8 registers per channel (mapped to the lower bytes of 16 words on the 68K)
  17.  
  18.     Reg:    Bits:        Meaning:
  19.  
  20.     0        7654 3210
  21.             ---- ---0    Key On / Off
  22.  
  23.     1        7654 ----    Volume L/R
  24.             ---- 3210    Volume R/L
  25.  
  26.     2                    ? (high byte?)
  27.     3                    ? (low  byte?)
  28.  
  29.     4                    Sample Start / 0x1000             [Start/End in bytes]
  30.     5                    0x100 - (Sample End / 0x1000)    [PCM ROM is Max 1MB?]
  31.  
  32.     6                    ?
  33.     7                    ?
  34.  
  35.  
  36. Hardcoded Values (for now):
  37.  
  38.     PCM ROM region:        REGION_SOUND1
  39.     Sample Frequency:    4, 6, 8 KHz
  40.  
  41. ***************************************************************************/
  42. #include "driver.h"
  43.  
  44. /* Variables and functions that driver has access to */
  45. unsigned char *seta_sound_ram;
  46.  
  47. #define SETA_NUM_CHANNELS 16
  48.  
  49. /* Variables only used here */
  50. static int firstchannel, frequency;
  51. static int seta_reg[SETA_NUM_CHANNELS][8];
  52.  
  53.  
  54.  
  55.  
  56. int seta_sh_start(const struct MachineSound *msound)
  57. {
  58.     int i;
  59.     int vol[MIXER_MAX_CHANNELS];
  60.  
  61.     for (i = 0;i < MIXER_MAX_CHANNELS;i++)    vol[i] = 100;
  62.     firstchannel = mixer_allocate_channels(SETA_NUM_CHANNELS,vol);
  63.  
  64.     for (i = 0; i < SETA_NUM_CHANNELS; i++)
  65.     {
  66.         char buf[40];
  67.         sprintf(buf,"X1-010 Channel #%d",i);
  68.         mixer_set_name(firstchannel + i,buf);
  69.     }
  70.     return 0;
  71. }
  72.  
  73. int seta_sh_start_4KHz(const struct MachineSound *msound)
  74. {
  75.     frequency = 4000;
  76.     return seta_sh_start(msound);
  77. }
  78.  
  79. int seta_sh_start_6KHz(const struct MachineSound *msound)
  80. {
  81.     frequency = 6000;
  82.     return seta_sh_start(msound);
  83. }
  84.  
  85. int seta_sh_start_8KHz(const struct MachineSound *msound)
  86. {
  87.     frequency = 8000;
  88.     return seta_sh_start(msound);
  89. }
  90.  
  91.  
  92.  
  93. /* Use these for 8 bit CPUs */
  94.  
  95.  
  96. READ_HANDLER( seta_sound_r )
  97. {
  98.     int channel    =    offset / 8;
  99.     int reg        =    offset % 8;
  100.  
  101.     if (channel < SETA_NUM_CHANNELS)
  102.     {
  103.         switch (reg)
  104.         {
  105.             case 0:
  106.                 return ( mixer_is_sample_playing(firstchannel + channel) ? 1 : 0 );
  107.             default:
  108.                 logerror("PC: %06X - X1-010 channel %X, register %X read!\n",cpu_get_pc(),channel,reg);
  109.                 return seta_reg[channel][reg];
  110.         }
  111.     }
  112.  
  113.     return seta_sound_ram[offset];
  114. }
  115.  
  116.  
  117.  
  118.  
  119. #define DUMP_REGS \
  120.     logerror("X1-010 REGS: %02X %02X %02X %02X - %02X %02X %02X %02X\n", \
  121.                             seta_reg[channel][0],seta_reg[channel][1], \
  122.                             seta_reg[channel][2],seta_reg[channel][3], \
  123.                             seta_reg[channel][4],seta_reg[channel][5], \
  124.                             seta_reg[channel][6],seta_reg[channel][7] );
  125.  
  126.  
  127. WRITE_HANDLER( seta_sound_w )
  128. {
  129.     int channel, reg;
  130.  
  131.     seta_sound_ram[offset] = data;
  132.  
  133.     if (Machine->sample_rate == 0)        return;
  134.  
  135.     channel    =    offset / 8;
  136.     reg        =    offset % 8;
  137.  
  138.     if (channel >= SETA_NUM_CHANNELS)    return;
  139.  
  140.     switch (reg)
  141.     {
  142.  
  143.         case 0:
  144.             if (data & 1)    // key on
  145.             {
  146.                 int volume    =    seta_reg[channel][1];
  147.  
  148.                 int start    =    seta_reg[channel][4]           * 0x1000;
  149.                 int end        =    (0x100 - seta_reg[channel][5]) * 0x1000; // from the end of the rom
  150.  
  151.                 int len        =    end - start;
  152.                 int maxlen    =    memory_region_length(REGION_SOUND1);
  153.  
  154.                 if (!( (start < end) && (end <= maxlen) ))
  155.                 {
  156.                     logerror("PC: %06X - X1-010 OUT OF RANGE SAMPLE: %06X - %06X, channel %X\n",cpu_get_pc(),start,end,channel);
  157.                     DUMP_REGS
  158.                     return;
  159.                 }
  160.  
  161. #if 1
  162. /* Print some more debug info */
  163. logerror("PC: %06X - Play 16 bit sample %06X - %06X, channel %X\n",cpu_get_pc(),start, end, channel);
  164. DUMP_REGS
  165. #endif
  166.  
  167.                 /*
  168.                    Twineagl continuosly writes 1 to reg 0 of the channel, so
  169.                    the sample is restarted every time and never plays to the
  170.                    end. It looks like the previous sample must be explicitly
  171.                    stopped before a new one can be played
  172.                 */
  173.                 if ( seta_sound_r(offset) & 1 )    return;    // play to the end
  174.  
  175.                 /* These samples are probaly looped and use the 3rd & 4th register's value */
  176.                 if (data & 2)    return;
  177.  
  178.                 /* left and right speaker's volume can be set indipendently.
  179.                    We use a mean volume for now */
  180.                 mixer_set_volume(firstchannel + channel, ((volume & 0xf)+(volume >> 4))*100/(2*0xf)  );
  181.  
  182.                 /* I assume the pitch is fixed for a given board. It ranges
  183.                    from 4 to 8 KHz for the games I've seen */
  184.  
  185.                 mixer_play_sample_16(
  186.                     firstchannel + channel,
  187.                     (short *) (memory_region(REGION_SOUND1) + start),    // start
  188.                     len,                                                // len
  189.                     frequency,                                            // frequency
  190.                     0);                                                    // loop
  191.             }
  192.             else
  193.                 mixer_stop_sample(channel + firstchannel);
  194.  
  195.             break;
  196.  
  197.         default:
  198.             seta_reg[channel][reg] = data & 0xff;
  199.  
  200.     }
  201. }
  202.  
  203.  
  204.  
  205.  
  206.  
  207. /* Use these for 16 bit CPUs */
  208.  
  209. READ_HANDLER( seta_sound_word_r )
  210. {
  211.     return seta_sound_r(offset/2) & 0xff;
  212. }
  213.  
  214. WRITE_HANDLER( seta_sound_word_w )
  215. {
  216.     if ( (data & 0x00ff0000) == 0 )
  217.         seta_sound_w(offset/2, data & 0xff);
  218. }
  219.